﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.MountAndBlade.View.Tableaus.TableauCacheManager
// Assembly: TaleWorlds.MountAndBlade.View, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 61152EB8-513B-4D4A-8AC0-0D1465C6CF6C
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\Modules\Native\bin\Win64_Shipping_Client\TaleWorlds.MountAndBlade.View.dll

using System;
using System.Collections.Generic;
using System.Linq;
using TaleWorlds.Core;
using TaleWorlds.DotNet;
using TaleWorlds.Engine;
using TaleWorlds.Library;
using TaleWorlds.MountAndBlade.View.Scripts;
using TaleWorlds.ObjectSystem;
using TaleWorlds.PlayerServices.Avatar;

#nullable disable
namespace TaleWorlds.MountAndBlade.View.Tableaus
{
  public class TableauCacheManager
  {
    private ThumbnailCreatorView _thumbnailCreatorView;
    private Scene _bannerScene;
    private Scene _inventoryScene;
    private bool _inventorySceneBeingUsed;
    private MBAgentRendererSceneController _inventorySceneAgentRenderer;
    private Scene _mapConversationScene;
    private bool _mapConversationSceneBeingUsed;
    private MBAgentRendererSceneController _mapConversationSceneAgentRenderer;
    private Camera _bannerCamera;
    private Camera _nineGridBannerCamera;
    private readonly ActionIndexCache act_tableau_hand_armor_pose = ActionIndexCache.Create(nameof (act_tableau_hand_armor_pose));
    private int _characterCount;
    private int _bannerCount;
    private Dictionary<string, TableauCacheManager.RenderDetails> _renderCallbacks;
    private ThumbnailCache _avatarVisuals;
    private ThumbnailCache _itemVisuals;
    private ThumbnailCache _craftingPieceVisuals;
    private ThumbnailCache _characterVisuals;
    private ThumbnailCache _bannerVisuals;
    private int bannerTableauGPUAllocationIndex;
    private int itemTableauGPUAllocationIndex;
    private int characterTableauGPUAllocationIndex;
    private Texture _heroSilhouetteTexture;

    public static TableauCacheManager Current { get; private set; }

    public MatrixFrame InventorySceneCameraFrame { get; private set; }

    private void InitializeThumbnailCreator()
    {
      this._thumbnailCreatorView = ThumbnailCreatorView.CreateThumbnailCreatorView();
      ThumbnailCreatorView.renderCallback += new ThumbnailCreatorView.OnThumbnailRenderCompleteDelegate(this.OnThumbnailRenderComplete);
      foreach (Scene tableauCharacterScene in BannerlordTableauManager.TableauCharacterScenes)
        this._thumbnailCreatorView.RegisterScene(tableauCharacterScene);
      this._bannerScene = Scene.CreateNewScene(enable_decals: false);
      this._bannerScene.DisableStaticShadows(true);
      this._bannerScene.SetName("TableauCacheManager.BannerScene");
      this._bannerScene.SetDefaultLighting();
      SceneInitializationData initData = new SceneInitializationData(true);
      initData.InitPhysicsWorld = false;
      initData.DoNotUseLoadingScreen = true;
      this._inventoryScene = Scene.CreateNewScene(enable_decals: false, atlasGroup: DecalAtlasGroup.Battle);
      this._inventoryScene.Read("inventory_character_scene", ref initData);
      this._inventoryScene.SetShadow(true);
      this._inventoryScene.DisableStaticShadows(true);
      this.InventorySceneCameraFrame = this._inventoryScene.FindEntityWithTag("camera_instance").GetGlobalFrame();
      this._inventorySceneAgentRenderer = MBAgentRendererSceneController.CreateNewAgentRendererSceneController(this._inventoryScene, 32);
      this._thumbnailCreatorView.RegisterScene(this._bannerScene, false);
      this.bannerTableauGPUAllocationIndex = Utilities.RegisterGPUAllocationGroup("BannerTableauCache");
      this.itemTableauGPUAllocationIndex = Utilities.RegisterGPUAllocationGroup("ItemTableauCache");
      this.characterTableauGPUAllocationIndex = Utilities.RegisterGPUAllocationGroup("CharacterTableauCache");
    }

    public bool IsCachedInventoryTableauSceneUsed() => this._inventorySceneBeingUsed;

    public Scene GetCachedInventoryTableauScene()
    {
      this._inventorySceneBeingUsed = true;
      return this._inventoryScene;
    }

    public void ReturnCachedInventoryTableauScene() => this._inventorySceneBeingUsed = false;

    public bool IsCachedMapConversationTableauSceneUsed() => this._mapConversationSceneBeingUsed;

    public Scene GetCachedMapConversationTableauScene()
    {
      this._mapConversationSceneBeingUsed = true;
      return this._mapConversationScene;
    }

    public void ReturnCachedMapConversationTableauScene()
    {
      this._mapConversationSceneBeingUsed = false;
    }

    public static int GetNumberOfPendingRequests()
    {
      return TableauCacheManager.Current != null ? TableauCacheManager.Current._thumbnailCreatorView.GetNumberOfPendingRequests() : 0;
    }

    public static bool IsNativeMemoryCleared()
    {
      return TableauCacheManager.Current != null && TableauCacheManager.Current._thumbnailCreatorView.IsMemoryCleared();
    }

    public static void InitializeManager()
    {
      TableauCacheManager.Current = new TableauCacheManager();
      TableauCacheManager.Current._renderCallbacks = new Dictionary<string, TableauCacheManager.RenderDetails>();
      TableauCacheManager.Current.InitializeThumbnailCreator();
      TableauCacheManager.Current._avatarVisuals = new ThumbnailCache(100, TableauCacheManager.Current._thumbnailCreatorView);
      TableauCacheManager.Current._itemVisuals = new ThumbnailCache(100, TableauCacheManager.Current._thumbnailCreatorView);
      TableauCacheManager.Current._craftingPieceVisuals = new ThumbnailCache(100, TableauCacheManager.Current._thumbnailCreatorView);
      TableauCacheManager.Current._characterVisuals = new ThumbnailCache(100, TableauCacheManager.Current._thumbnailCreatorView);
      TableauCacheManager.Current._bannerVisuals = new ThumbnailCache(100, TableauCacheManager.Current._thumbnailCreatorView);
      TableauCacheManager.Current._bannerCamera = TableauCacheManager.CreateDefaultBannerCamera();
      TableauCacheManager.Current._nineGridBannerCamera = TableauCacheManager.CreateNineGridBannerCamera();
      TableauCacheManager.Current._heroSilhouetteTexture = Texture.GetFromResource("hero_silhouette");
    }

    public static void InitializeSandboxValues()
    {
      SceneInitializationData initData = new SceneInitializationData(true);
      initData.InitPhysicsWorld = false;
      TableauCacheManager.Current._mapConversationScene = Scene.CreateNewScene(enable_decals: false);
      TableauCacheManager.Current._mapConversationScene.SetName("MapConversationTableau");
      TableauCacheManager.Current._mapConversationScene.DisableStaticShadows(true);
      TableauCacheManager.Current._mapConversationScene.Read("scn_conversation_tableau", ref initData);
      TableauCacheManager.Current._mapConversationScene.SetShadow(true);
      TableauCacheManager.Current._mapConversationSceneAgentRenderer = MBAgentRendererSceneController.CreateNewAgentRendererSceneController(TableauCacheManager.Current._mapConversationScene, 32);
      Utilities.LoadVirtualTextureTileset("WorldMap");
    }

    public static void ReleaseSandboxValues()
    {
      MBAgentRendererSceneController.DestructAgentRendererSceneController(TableauCacheManager.Current._mapConversationScene, TableauCacheManager.Current._mapConversationSceneAgentRenderer, false);
      TableauCacheManager.Current._mapConversationSceneAgentRenderer = (MBAgentRendererSceneController) null;
      TableauCacheManager.Current._mapConversationScene.ClearAll();
      TableauCacheManager.Current._mapConversationScene.ManualInvalidate();
      TableauCacheManager.Current._mapConversationScene = (Scene) null;
    }

    public static void ClearManager()
    {
      Debug.Print("TableauCacheManager::ClearManager");
      if (TableauCacheManager.Current == null)
        return;
      TableauCacheManager.Current._renderCallbacks = (Dictionary<string, TableauCacheManager.RenderDetails>) null;
      TableauCacheManager.Current._avatarVisuals = (ThumbnailCache) null;
      TableauCacheManager.Current._itemVisuals = (ThumbnailCache) null;
      TableauCacheManager.Current._craftingPieceVisuals = (ThumbnailCache) null;
      TableauCacheManager.Current._characterVisuals = (ThumbnailCache) null;
      TableauCacheManager.Current._bannerVisuals = (ThumbnailCache) null;
      TableauCacheManager.Current._bannerCamera?.ReleaseCamera();
      TableauCacheManager.Current._bannerCamera = (Camera) null;
      TableauCacheManager.Current._nineGridBannerCamera?.ReleaseCamera();
      TableauCacheManager.Current._nineGridBannerCamera = (Camera) null;
      MBAgentRendererSceneController.DestructAgentRendererSceneController(TableauCacheManager.Current._inventoryScene, TableauCacheManager.Current._inventorySceneAgentRenderer, true);
      TableauCacheManager.Current._inventoryScene?.ManualInvalidate();
      TableauCacheManager.Current._inventoryScene = (Scene) null;
      TableauCacheManager.Current._bannerScene?.ClearDecals();
      TableauCacheManager.Current._bannerScene?.ClearAll();
      TableauCacheManager.Current._bannerScene?.ManualInvalidate();
      TableauCacheManager.Current._bannerScene = (Scene) null;
      ThumbnailCreatorView.renderCallback -= new ThumbnailCreatorView.OnThumbnailRenderCompleteDelegate(TableauCacheManager.Current.OnThumbnailRenderComplete);
      TableauCacheManager.Current._thumbnailCreatorView.ClearRequests();
      TableauCacheManager.Current._thumbnailCreatorView = (ThumbnailCreatorView) null;
      TableauCacheManager.Current = (TableauCacheManager) null;
    }

    private string ByteWidthToString(int bytes)
    {
      double num1 = Math.Log((double) bytes);
      if (bytes == 0)
        num1 = 0.0;
      int num2 = (int) (num1 / Math.Log(1024.0));
      char ch = " KMGTPE"[num2];
      return ((double) bytes / Math.Pow(1024.0, (double) num2)).ToString("0.00") + " " + ch.ToString() + "      ";
    }

    private void PrintTextureToImgui(string name, ThumbnailCache cache)
    {
      int totalMemorySize = cache.GetTotalMemorySize();
      Imgui.Text(name);
      Imgui.NextColumn();
      Imgui.Text(cache.Count.ToString());
      Imgui.NextColumn();
      Imgui.Text(this.ByteWidthToString(totalMemorySize));
      Imgui.NextColumn();
    }

    public void OnImguiProfilerTick()
    {
      Imgui.BeginMainThreadScope();
      Imgui.Begin("Tableau Cache Manager");
      Imgui.Columns(3);
      Imgui.Text("Name");
      Imgui.NextColumn();
      Imgui.Text("Count");
      Imgui.NextColumn();
      Imgui.Text("Memory");
      Imgui.NextColumn();
      Imgui.Separator();
      this.PrintTextureToImgui("Items", this._itemVisuals);
      this.PrintTextureToImgui("Banners", this._bannerVisuals);
      this.PrintTextureToImgui("Characters", this._characterVisuals);
      this.PrintTextureToImgui("Avatars", this._avatarVisuals);
      this.PrintTextureToImgui("Crafting Pieces", this._craftingPieceVisuals);
      Imgui.Text("Render Callbacks");
      Imgui.NextColumn();
      Imgui.Text(this._renderCallbacks.Count<KeyValuePair<string, TableauCacheManager.RenderDetails>>().ToString());
      Imgui.NextColumn();
      Imgui.Text("-");
      Imgui.NextColumn();
      Imgui.End();
      Imgui.EndMainThreadScope();
    }

    private void OnThumbnailRenderComplete(string renderId, Texture renderTarget)
    {
      Texture texture = (Texture) null;
      if (this._itemVisuals.GetValue(renderId, out texture))
        this._itemVisuals.Add(renderId, renderTarget);
      else if (this._craftingPieceVisuals.GetValue(renderId, out texture))
        this._craftingPieceVisuals.Add(renderId, renderTarget);
      else if (this._characterVisuals.GetValue(renderId, out texture))
        this._characterVisuals.Add(renderId, renderTarget);
      else if (!this._avatarVisuals.GetValue(renderId, out texture) && !this._bannerVisuals.GetValue(renderId, out texture))
        renderTarget.Release();
      if (!this._renderCallbacks.ContainsKey(renderId))
        return;
      foreach (Action<Texture> action in this._renderCallbacks[renderId].Actions)
      {
        if (action != null)
          action(renderTarget);
      }
      this._renderCallbacks.Remove(renderId);
    }

    public Texture CreateAvatarTexture(
      string avatarID,
      byte[] avatarBytes,
      uint width,
      uint height,
      AvatarData.ImageType imageType)
    {
      Texture texture;
      this._avatarVisuals.GetValue(avatarID, out texture);
      if ((NativeObject) texture == (NativeObject) null)
      {
        switch (imageType)
        {
          case AvatarData.ImageType.Image:
            texture = Texture.CreateFromMemory(avatarBytes);
            break;
          case AvatarData.ImageType.Raw:
            texture = Texture.CreateFromByteArray(avatarBytes, (int) width, (int) height);
            break;
        }
        this._avatarVisuals.Add(avatarID, texture);
      }
      this._avatarVisuals.AddReference(avatarID);
      return texture;
    }

    public void BeginCreateItemTexture(
      ItemObject itemObject,
      string additionalArgs,
      Action<Texture> setAction)
    {
      string str = itemObject.StringId;
      if (itemObject.Type == ItemObject.ItemTypeEnum.Shield)
        str = str + "_" + additionalArgs;
      Texture texture;
      if (this._itemVisuals.GetValue(str, out texture))
      {
        if (this._renderCallbacks.ContainsKey(str))
          this._renderCallbacks[str].Actions.Add(setAction);
        else if (setAction != null)
          setAction(texture);
        this._itemVisuals.AddReference(str);
      }
      else
      {
        Camera camera = (Camera) null;
        int index = 2;
        int width = 256;
        int height = 120;
        GameEntity itemBaseEntity = this.CreateItemBaseEntity(itemObject, BannerlordTableauManager.TableauCharacterScenes[index], ref camera);
        this._thumbnailCreatorView.RegisterEntityWithoutTexture(BannerlordTableauManager.TableauCharacterScenes[index], camera, itemBaseEntity, width, height, this.itemTableauGPUAllocationIndex, str, "item_tableau_" + str);
        itemBaseEntity.ManualInvalidate();
        this._itemVisuals.Add(str, (Texture) null);
        this._itemVisuals.AddReference(str);
        if (!this._renderCallbacks.ContainsKey(str))
          this._renderCallbacks.Add(str, new TableauCacheManager.RenderDetails(new List<Action<Texture>>()));
        this._renderCallbacks[str].Actions.Add(setAction);
      }
    }

    public void BeginCreateCraftingPieceTexture(
      CraftingPiece craftingPiece,
      string type,
      Action<Texture> setAction)
    {
      string str = craftingPiece.StringId + "$" + type;
      Texture texture;
      if (this._craftingPieceVisuals.GetValue(str, out texture))
      {
        if (this._renderCallbacks.ContainsKey(str))
          this._renderCallbacks[str].Actions.Add(setAction);
        else if (setAction != null)
          setAction(texture);
        this._craftingPieceVisuals.AddReference(str);
      }
      else
      {
        Camera camera = (Camera) null;
        int index = 2;
        int width = 256;
        int height = 180;
        GameEntity craftingPieceBaseEntity = this.CreateCraftingPieceBaseEntity(craftingPiece, type, BannerlordTableauManager.TableauCharacterScenes[index], ref camera);
        this._thumbnailCreatorView.RegisterEntityWithoutTexture(BannerlordTableauManager.TableauCharacterScenes[index], camera, craftingPieceBaseEntity, width, height, this.itemTableauGPUAllocationIndex, str, "craft_tableau");
        craftingPieceBaseEntity.ManualInvalidate();
        this._craftingPieceVisuals.Add(str, (Texture) null);
        this._craftingPieceVisuals.AddReference(str);
        if (!this._renderCallbacks.ContainsKey(str))
          this._renderCallbacks.Add(str, new TableauCacheManager.RenderDetails(new List<Action<Texture>>()));
        this._renderCallbacks[str].Actions.Add(setAction);
      }
    }

    public void BeginCreateCharacterTexture(
      CharacterCode characterCode,
      Action<Texture> setAction,
      bool isBig)
    {
      if (MBObjectManager.Instance == null)
        return;
      CharacterCode characterCode1 = characterCode;
      characterCode1.BodyProperties = new BodyProperties(new DynamicBodyProperties((float) (int) characterCode.BodyProperties.Age, (float) (int) characterCode.BodyProperties.Weight, (float) (int) characterCode.BodyProperties.Build), characterCode1.BodyProperties.StaticProperties);
      string str = characterCode1.CreateNewCodeString() + (isBig ? "1" : "0");
      Texture texture;
      if (this._characterVisuals.GetValue(str, out texture))
      {
        if (this._renderCallbacks.ContainsKey(str))
          this._renderCallbacks[str].Actions.Add(setAction);
        else if (setAction != null)
          setAction(texture);
        this._characterVisuals.AddReference(str);
      }
      else
      {
        Camera camera = (Camera) null;
        int index = isBig ? 0 : 4;
        GameEntity characterBaseEntity = this.CreateCharacterBaseEntity(characterCode, BannerlordTableauManager.TableauCharacterScenes[index], ref camera, isBig);
        GameEntity entity = this.FillEntityWithPose(characterCode, characterBaseEntity, BannerlordTableauManager.TableauCharacterScenes[index]);
        int width = 256;
        int height = isBig ? 120 : 184;
        this._thumbnailCreatorView.RegisterEntityWithoutTexture(BannerlordTableauManager.TableauCharacterScenes[index], camera, entity, width, height, this.characterTableauGPUAllocationIndex, str, "character_tableau_" + this._characterCount.ToString());
        entity.ManualInvalidate();
        ++this._characterCount;
        this._characterVisuals.Add(str, (Texture) null);
        this._characterVisuals.AddReference(str);
        if (!this._renderCallbacks.ContainsKey(str))
          this._renderCallbacks.Add(str, new TableauCacheManager.RenderDetails(new List<Action<Texture>>()));
        this._renderCallbacks[str].Actions.Add(setAction);
      }
    }

    public Texture GetCachedHeroSilhouetteTexture() => this._heroSilhouetteTexture;

    public Texture BeginCreateBannerTexture(
      BannerCode bannerCode,
      Action<Texture> setAction,
      bool isTableauOrNineGrid = false,
      bool isLarge = false)
    {
      int width = 512;
      int height = 512;
      Camera cam = this._bannerCamera;
      string str1 = "BannerThumbnail";
      if (isTableauOrNineGrid)
      {
        cam = this._nineGridBannerCamera;
        if (isLarge)
        {
          width = 1024;
          height = 1024;
          str1 = "BannerTableauLarge";
        }
        else
          str1 = "BannerTableauSmall";
      }
      string str2 = str1 + ":" + bannerCode.Code;
      Texture texture;
      if (this._bannerVisuals.GetValue(str2, out texture))
      {
        if (this._renderCallbacks.ContainsKey(str2))
          this._renderCallbacks[str2].Actions.Add(setAction);
        else if (setAction != null)
          setAction(texture);
        this._bannerVisuals.AddReference(str2);
        return texture;
      }
      MatrixFrame identity = MatrixFrame.Identity;
      Banner banner = bannerCode.CalculateBanner();
      if (Game.Current == null)
        banner.SetBannerVisual(((IBannerVisualCreator) new BannerVisualCreator()).CreateBannerVisual(banner));
      MetaMesh multiMesh = banner.ConvertToMultiMesh();
      GameEntity itemEntity = this._bannerScene.AddItemEntity(ref identity, multiMesh);
      multiMesh.ManualInvalidate();
      itemEntity.SetVisibilityExcludeParents(false);
      Texture renderTarget = Texture.CreateRenderTarget(str1 + this._bannerCount.ToString(), width, height, true, false, true, true);
      this._thumbnailCreatorView.RegisterEntity(this._bannerScene, cam, renderTarget, itemEntity, this.bannerTableauGPUAllocationIndex, str2);
      this._bannerVisuals.Add(str2, renderTarget);
      this._bannerVisuals.AddReference(str2);
      ++this._bannerCount;
      if (!this._renderCallbacks.ContainsKey(str2))
        this._renderCallbacks.Add(str2, new TableauCacheManager.RenderDetails(new List<Action<Texture>>()));
      this._renderCallbacks[str2].Actions.Add(setAction);
      return renderTarget;
    }

    public void Tick()
    {
      this._avatarVisuals?.Tick();
      this._itemVisuals?.Tick();
      this._craftingPieceVisuals?.Tick();
      this._characterVisuals?.Tick();
      this._bannerVisuals?.Tick();
    }

    public void ReleaseTextureWithId(CraftingPiece craftingPiece, string type)
    {
      this._craftingPieceVisuals.MarkForDeletion(craftingPiece.StringId + "$" + type);
    }

    public void ReleaseTextureWithId(CharacterCode characterCode, bool isBig)
    {
      CharacterCode characterCode1 = characterCode;
      characterCode1.BodyProperties = new BodyProperties(new DynamicBodyProperties((float) (int) characterCode.BodyProperties.Age, (float) (int) characterCode.BodyProperties.Weight, (float) (int) characterCode.BodyProperties.Build), characterCode1.BodyProperties.StaticProperties);
      this._characterVisuals.MarkForDeletion(characterCode1.CreateNewCodeString() + (isBig ? "1" : "0"));
    }

    public void ReleaseTextureWithId(ItemObject itemObject)
    {
      this._itemVisuals.MarkForDeletion(itemObject.StringId);
    }

    public void ReleaseTextureWithId(BannerCode bannerCode, bool isTableau = false, bool isLarge = false)
    {
      string str = "BannerThumbnail";
      if (isTableau)
        str = !isLarge ? "BannerTableauSmall" : "BannerTableauLarge";
      this._bannerVisuals.MarkForDeletion(str + ":" + bannerCode.Code);
    }

    public void ForceReleaseBanner(BannerCode bannerCode, bool isTableau = false, bool isLarge = false)
    {
      string str = "BannerThumbnail";
      if (isTableau)
        str = !isLarge ? "BannerTableauSmall" : "BannerTableauLarge";
      this._bannerVisuals.ForceDelete(str + ":" + bannerCode.Code);
    }

    private void GetItemPoseAndCameraForCraftedItem(
      ItemObject item,
      Scene scene,
      ref Camera camera,
      ref MatrixFrame itemFrame,
      ref MatrixFrame itemFrame1,
      ref MatrixFrame itemFrame2)
    {
      if ((NativeObject) camera == (NativeObject) null)
        camera = Camera.CreateCamera();
      itemFrame = MatrixFrame.Identity;
      WeaponClass weaponClass = item.WeaponDesign.Template.WeaponDescriptions[0].WeaponClass;
      Vec3 u = itemFrame.rotation.u;
      Vec3 vec3_1 = itemFrame.origin - u * (item.WeaponDesign.CraftedWeaponLength * 0.5f);
      Vec3 v1 = vec3_1 + u * item.WeaponDesign.CraftedWeaponLength;
      Vec3 v2 = vec3_1 - u * item.WeaponDesign.BottomPivotOffset;
      int num = 0;
      Vec3 v3 = new Vec3();
      foreach (float topPivotOffset in item.WeaponDesign.TopPivotOffsets)
      {
        if ((double) topPivotOffset > (double) MathF.Abs(1E-05f))
        {
          Vec3 vec3_2 = vec3_1 + u * topPivotOffset;
          if (num == 1)
            v3 = vec3_2;
          ++num;
        }
      }
      if (weaponClass == WeaponClass.OneHandedSword || weaponClass == WeaponClass.TwoHandedSword)
      {
        GameEntity entityWithTag1 = scene.FindEntityWithTag("sword_camera");
        Vec3 dofParams = new Vec3();
        entityWithTag1.GetCameraParamsFromCameraScript(camera, ref dofParams);
        entityWithTag1.SetVisibilityExcludeParents(false);
        Vec3 local = itemFrame.TransformToLocal(v2);
        MatrixFrame identity = MatrixFrame.Identity with
        {
          origin = -local
        };
        GameEntity entityWithTag2 = scene.FindEntityWithTag("sword");
        entityWithTag2.SetVisibilityExcludeParents(false);
        itemFrame = entityWithTag2.GetGlobalFrame();
        itemFrame = itemFrame.TransformToParent(identity);
      }
      if (weaponClass == WeaponClass.OneHandedAxe || weaponClass == WeaponClass.TwoHandedAxe)
      {
        GameEntity entityWithTag3 = scene.FindEntityWithTag("axe_camera");
        Vec3 dofParams = new Vec3();
        entityWithTag3.GetCameraParamsFromCameraScript(camera, ref dofParams);
        entityWithTag3.SetVisibilityExcludeParents(false);
        Vec3 local = itemFrame.TransformToLocal(v3);
        MatrixFrame identity = MatrixFrame.Identity with
        {
          origin = -local
        };
        GameEntity entityWithTag4 = scene.FindEntityWithTag("axe");
        entityWithTag4.SetVisibilityExcludeParents(false);
        itemFrame = entityWithTag4.GetGlobalFrame();
        itemFrame = itemFrame.TransformToParent(identity);
      }
      if (weaponClass == WeaponClass.Dagger)
      {
        GameEntity entityWithTag5 = scene.FindEntityWithTag("sword_camera");
        Vec3 dofParams = new Vec3();
        entityWithTag5.GetCameraParamsFromCameraScript(camera, ref dofParams);
        entityWithTag5.SetVisibilityExcludeParents(false);
        Vec3 local = itemFrame.TransformToLocal(v2);
        MatrixFrame identity = MatrixFrame.Identity with
        {
          origin = -local
        };
        GameEntity entityWithTag6 = scene.FindEntityWithTag("sword");
        entityWithTag6.SetVisibilityExcludeParents(false);
        itemFrame = entityWithTag6.GetGlobalFrame();
        itemFrame = itemFrame.TransformToParent(identity);
      }
      if (weaponClass == WeaponClass.ThrowingAxe)
      {
        GameEntity entityWithTag7 = scene.FindEntityWithTag("throwing_axe_camera");
        Vec3 dofParams = new Vec3();
        entityWithTag7.GetCameraParamsFromCameraScript(camera, ref dofParams);
        entityWithTag7.SetVisibilityExcludeParents(false);
        Vec3 v4 = vec3_1 + u * item.PrimaryWeapon.CenterOfMass;
        Vec3 local = itemFrame.TransformToLocal(v4);
        MatrixFrame identity = MatrixFrame.Identity with
        {
          origin = -local * 2.5f
        };
        GameEntity entityWithTag8 = scene.FindEntityWithTag("throwing_axe");
        entityWithTag8.SetVisibilityExcludeParents(false);
        itemFrame = entityWithTag8.GetGlobalFrame();
        itemFrame = itemFrame.TransformToParent(identity);
        GameEntity entityWithTag9 = scene.FindEntityWithTag("throwing_axe_1");
        entityWithTag9.SetVisibilityExcludeParents(false);
        itemFrame1 = entityWithTag9.GetGlobalFrame();
        itemFrame1 = itemFrame1.TransformToParent(identity);
        GameEntity entityWithTag10 = scene.FindEntityWithTag("throwing_axe_2");
        entityWithTag10.SetVisibilityExcludeParents(false);
        itemFrame2 = entityWithTag10.GetGlobalFrame();
        itemFrame2 = itemFrame2.TransformToParent(identity);
      }
      if (weaponClass == WeaponClass.Javelin)
      {
        GameEntity entityWithTag11 = scene.FindEntityWithTag("javelin_camera");
        Vec3 dofParams = new Vec3();
        entityWithTag11.GetCameraParamsFromCameraScript(camera, ref dofParams);
        entityWithTag11.SetVisibilityExcludeParents(false);
        Vec3 local = itemFrame.TransformToLocal(v3);
        MatrixFrame identity = MatrixFrame.Identity with
        {
          origin = -local * 2.2f
        };
        GameEntity entityWithTag12 = scene.FindEntityWithTag("javelin");
        entityWithTag12.SetVisibilityExcludeParents(false);
        itemFrame = entityWithTag12.GetGlobalFrame();
        itemFrame = itemFrame.TransformToParent(identity);
        GameEntity entityWithTag13 = scene.FindEntityWithTag("javelin_1");
        entityWithTag13.SetVisibilityExcludeParents(false);
        itemFrame1 = entityWithTag13.GetGlobalFrame();
        itemFrame1 = itemFrame1.TransformToParent(identity);
        GameEntity entityWithTag14 = scene.FindEntityWithTag("javelin_2");
        entityWithTag14.SetVisibilityExcludeParents(false);
        itemFrame2 = entityWithTag14.GetGlobalFrame();
        itemFrame2 = itemFrame2.TransformToParent(identity);
      }
      if (weaponClass == WeaponClass.ThrowingKnife)
      {
        GameEntity entityWithTag15 = scene.FindEntityWithTag("javelin_camera");
        Vec3 dofParams = new Vec3();
        entityWithTag15.GetCameraParamsFromCameraScript(camera, ref dofParams);
        entityWithTag15.SetVisibilityExcludeParents(false);
        Vec3 local = itemFrame.TransformToLocal(v1);
        MatrixFrame identity = MatrixFrame.Identity with
        {
          origin = -local * 1.4f
        };
        GameEntity entityWithTag16 = scene.FindEntityWithTag("javelin");
        entityWithTag16.SetVisibilityExcludeParents(false);
        itemFrame = entityWithTag16.GetGlobalFrame();
        itemFrame = itemFrame.TransformToParent(identity);
        GameEntity entityWithTag17 = scene.FindEntityWithTag("javelin_1");
        entityWithTag17.SetVisibilityExcludeParents(false);
        itemFrame1 = entityWithTag17.GetGlobalFrame();
        itemFrame1 = itemFrame1.TransformToParent(identity);
        GameEntity entityWithTag18 = scene.FindEntityWithTag("javelin_2");
        entityWithTag18.SetVisibilityExcludeParents(false);
        itemFrame2 = entityWithTag18.GetGlobalFrame();
        itemFrame2 = itemFrame2.TransformToParent(identity);
      }
      if (weaponClass != WeaponClass.TwoHandedPolearm && weaponClass != WeaponClass.OneHandedPolearm && weaponClass != WeaponClass.LowGripPolearm && weaponClass != WeaponClass.Mace && weaponClass != WeaponClass.TwoHandedMace)
        return;
      GameEntity entityWithTag19 = scene.FindEntityWithTag("spear_camera");
      Vec3 dofParams1 = new Vec3();
      entityWithTag19.GetCameraParamsFromCameraScript(camera, ref dofParams1);
      entityWithTag19.SetVisibilityExcludeParents(false);
      Vec3 local1 = itemFrame.TransformToLocal(v3);
      MatrixFrame identity1 = MatrixFrame.Identity with
      {
        origin = -local1
      };
      GameEntity entityWithTag20 = scene.FindEntityWithTag("spear");
      entityWithTag20.SetVisibilityExcludeParents(false);
      itemFrame = entityWithTag20.GetGlobalFrame();
      itemFrame = itemFrame.TransformToParent(identity1);
    }

    private void GetItemPoseAndCamera(
      ItemObject item,
      Scene scene,
      ref Camera camera,
      ref MatrixFrame itemFrame,
      ref MatrixFrame itemFrame1,
      ref MatrixFrame itemFrame2)
    {
      if (item.IsCraftedWeapon)
      {
        this.GetItemPoseAndCameraForCraftedItem(item, scene, ref camera, ref itemFrame, ref itemFrame1, ref itemFrame2);
      }
      else
      {
        string str = "";
        TableauCacheManager.CustomPoseParameters customPoseParameters1 = new TableauCacheManager.CustomPoseParameters();
        customPoseParameters1.CameraTag = "goods_cam";
        customPoseParameters1.DistanceModifier = 6f;
        customPoseParameters1.FrameTag = "goods_frame";
        TableauCacheManager.CustomPoseParameters customPoseParameters2 = customPoseParameters1;
        if (item.WeaponComponent != null)
        {
          switch (item.WeaponComponent.PrimaryWeapon.WeaponClass)
          {
            case WeaponClass.OneHandedSword:
            case WeaponClass.TwoHandedSword:
              str = "sword";
              break;
          }
        }
        else
        {
          switch (item.Type)
          {
            case ItemObject.ItemTypeEnum.HeadArmor:
              str = "helmet";
              break;
            case ItemObject.ItemTypeEnum.BodyArmor:
              str = "armor";
              break;
          }
        }
        if (item.Type == ItemObject.ItemTypeEnum.Shield)
          str = "shield";
        if (item.Type == ItemObject.ItemTypeEnum.Crossbow)
          str = "crossbow";
        if (item.Type == ItemObject.ItemTypeEnum.Bow)
          str = "bow";
        if (item.Type == ItemObject.ItemTypeEnum.LegArmor)
          str = "boot";
        if (item.Type == ItemObject.ItemTypeEnum.Horse)
          str = ((HorseComponent) item.ItemComponent).Monster.MonsterUsage;
        if (item.Type == ItemObject.ItemTypeEnum.HorseHarness)
          str = "horse";
        if (item.Type == ItemObject.ItemTypeEnum.Cape)
          str = "cape";
        if (item.Type == ItemObject.ItemTypeEnum.HandArmor)
          str = "glove";
        if (item.Type == ItemObject.ItemTypeEnum.Arrows)
          str = "arrow";
        if (item.Type == ItemObject.ItemTypeEnum.Bolts)
          str = "bolt";
        if (item.Type == ItemObject.ItemTypeEnum.Banner)
        {
          customPoseParameters1 = new TableauCacheManager.CustomPoseParameters();
          customPoseParameters1.CameraTag = "banner_cam";
          customPoseParameters1.DistanceModifier = 1.5f;
          customPoseParameters1.FrameTag = "banner_frame";
          customPoseParameters1.FocusAlignment = TableauCacheManager.CustomPoseParameters.Alignment.Top;
          customPoseParameters2 = customPoseParameters1;
        }
        if (item.Type == ItemObject.ItemTypeEnum.Animal)
        {
          customPoseParameters1 = new TableauCacheManager.CustomPoseParameters();
          customPoseParameters1.CameraTag = customPoseParameters2.CameraTag;
          customPoseParameters1.DistanceModifier = 3f;
          customPoseParameters1.FrameTag = customPoseParameters2.FrameTag;
          customPoseParameters2 = customPoseParameters1;
        }
        if (item.StringId == "iron" || item.StringId == "hardwood" || item.StringId == "charcoal" || item.StringId == "ironIngot1" || item.StringId == "ironIngot2" || item.StringId == "ironIngot3" || item.StringId == "ironIngot4" || item.StringId == "ironIngot5" || item.StringId == "ironIngot6" || item.ItemCategory == DefaultItemCategories.Silver)
          str = "craftmat";
        if (!string.IsNullOrEmpty(str))
        {
          string tag1 = str + "_cam";
          string tag2 = str + "_frame";
          GameEntity entityWithTag1 = scene.FindEntityWithTag(tag1);
          if ((NativeObject) entityWithTag1 != (NativeObject) null)
          {
            camera = Camera.CreateCamera();
            Vec3 dofParams = new Vec3();
            entityWithTag1.GetCameraParamsFromCameraScript(camera, ref dofParams);
          }
          GameEntity entityWithTag2 = scene.FindEntityWithTag(tag2);
          if ((NativeObject) entityWithTag2 != (NativeObject) null)
          {
            itemFrame = entityWithTag2.GetGlobalFrame();
            entityWithTag2.SetVisibilityExcludeParents(false);
          }
        }
        else
        {
          GameEntity entityWithTag3 = scene.FindEntityWithTag(customPoseParameters2.CameraTag);
          if ((NativeObject) entityWithTag3 != (NativeObject) null)
          {
            camera = Camera.CreateCamera();
            Vec3 dofParams = new Vec3();
            entityWithTag3.GetCameraParamsFromCameraScript(camera, ref dofParams);
          }
          GameEntity entityWithTag4 = scene.FindEntityWithTag(customPoseParameters2.FrameTag);
          if ((NativeObject) entityWithTag4 != (NativeObject) null)
          {
            itemFrame = entityWithTag4.GetGlobalFrame();
            entityWithTag4.SetVisibilityExcludeParents(false);
            entityWithTag4.UpdateGlobalBounds();
            MatrixFrame globalFrame1 = entityWithTag4.GetGlobalFrame();
            MetaMesh meshForInventory = new ItemRosterElement(item).GetItemMeshForInventory();
            Vec3 v1_1 = new Vec3(1000000f, 1000000f, 1000000f);
            Vec3 v1_2 = new Vec3(-1000000f, -1000000f, -1000000f);
            if ((NativeObject) meshForInventory != (NativeObject) null)
            {
              MatrixFrame identity = MatrixFrame.Identity;
              for (int meshIndex = 0; meshIndex != meshForInventory.MeshCount; ++meshIndex)
              {
                Vec3 boundingBoxMin = meshForInventory.GetMeshAtIndex(meshIndex).GetBoundingBoxMin();
                Vec3 boundingBoxMax = meshForInventory.GetMeshAtIndex(meshIndex).GetBoundingBoxMax();
                Vec3[] vec3Array = new Vec3[8]
                {
                  globalFrame1.TransformToParent(new Vec3(boundingBoxMin.x, boundingBoxMin.y, boundingBoxMin.z)),
                  globalFrame1.TransformToParent(new Vec3(boundingBoxMin.x, boundingBoxMin.y, boundingBoxMax.z)),
                  globalFrame1.TransformToParent(new Vec3(boundingBoxMin.x, boundingBoxMax.y, boundingBoxMin.z)),
                  globalFrame1.TransformToParent(new Vec3(boundingBoxMin.x, boundingBoxMax.y, boundingBoxMax.z)),
                  globalFrame1.TransformToParent(new Vec3(boundingBoxMax.x, boundingBoxMin.y, boundingBoxMin.z)),
                  globalFrame1.TransformToParent(new Vec3(boundingBoxMax.x, boundingBoxMin.y, boundingBoxMax.z)),
                  globalFrame1.TransformToParent(new Vec3(boundingBoxMax.x, boundingBoxMax.y, boundingBoxMin.z)),
                  globalFrame1.TransformToParent(new Vec3(boundingBoxMax.x, boundingBoxMax.y, boundingBoxMax.z))
                };
                for (int index = 0; index < 8; ++index)
                {
                  v1_1 = Vec3.Vec3Min(v1_1, vec3Array[index]);
                  v1_2 = Vec3.Vec3Max(v1_2, vec3Array[index]);
                }
              }
            }
            Vec3 v = (v1_1 + v1_2) * 0.5f;
            Vec3 local1 = entityWithTag4.GetGlobalFrame().TransformToLocal(v);
            MatrixFrame globalFrame2 = entityWithTag4.GetGlobalFrame();
            globalFrame2.origin -= local1;
            itemFrame = globalFrame2;
            MatrixFrame frame = camera.Frame;
            Vec3 vec3_1 = v1_2 - v1_1;
            float num = vec3_1.Length * customPoseParameters2.DistanceModifier;
            frame.origin += frame.rotation.u * num;
            if (customPoseParameters2.FocusAlignment == TableauCacheManager.CustomPoseParameters.Alignment.Top)
            {
              ref Vec3 local2 = ref frame.origin;
              Vec3 vec3_2 = local2;
              vec3_1 = v1_2 - v1_1;
              Vec3 vec3_3 = new Vec3(z: (float) ((double) vec3_1.Z * 0.30000001192092896));
              local2 = vec3_2 + vec3_3;
            }
            else if (customPoseParameters2.FocusAlignment == TableauCacheManager.CustomPoseParameters.Alignment.Bottom)
            {
              ref Vec3 local3 = ref frame.origin;
              Vec3 vec3_4 = local3;
              vec3_1 = v1_2 - v1_1;
              Vec3 vec3_5 = new Vec3(z: (float) ((double) vec3_1.Z * 0.30000001192092896));
              local3 = vec3_4 - vec3_5;
            }
            camera.Frame = frame;
          }
        }
        if ((NativeObject) camera == (NativeObject) null)
        {
          camera = Camera.CreateCamera();
          camera.SetViewVolume(false, -1f, 1f, -0.5f, 0.5f, 0.01f, 100f);
          MatrixFrame identity = MatrixFrame.Identity;
          identity.origin -= identity.rotation.u * 7f;
          identity.rotation.u *= -1f;
          camera.Frame = identity;
        }
        if (item.Type != ItemObject.ItemTypeEnum.Shield)
          return;
        GameEntity entityWithTag = scene.FindEntityWithTag("shield_cam");
        MatrixFrame holsterFrameByIndex = MBItem.GetHolsterFrameByIndex(MBItem.GetItemHolsterIndex(item.ItemHolsters[0]));
        itemFrame.rotation = holsterFrameByIndex.rotation;
        MatrixFrame parent = itemFrame.TransformToParent(entityWithTag.GetFrame());
        camera.Frame = parent;
      }
    }

    private GameEntity AddItem(
      Scene scene,
      ItemObject item,
      MatrixFrame itemFrame,
      MatrixFrame itemFrame1,
      MatrixFrame itemFrame2)
    {
      ItemRosterElement rosterElement = new ItemRosterElement(item);
      MetaMesh meshForInventory = rosterElement.GetItemMeshForInventory();
      if (item.IsCraftedWeapon)
      {
        MatrixFrame frame = meshForInventory.Frame;
        frame.Elevate((float) (-(double) item.WeaponDesign.CraftedWeaponLength / 2.0));
        meshForInventory.Frame = frame;
      }
      GameEntity gameEntity = (GameEntity) null;
      if ((NativeObject) meshForInventory != (NativeObject) null && rosterElement.EquipmentElement.Item.ItemType == ItemObject.ItemTypeEnum.HandArmor)
      {
        gameEntity = GameEntity.CreateEmpty(scene);
        AnimationSystemData animationSystemData = Game.Current.DefaultMonster.FillAnimationSystemData(MBActionSet.GetActionSet(Game.Current.DefaultMonster.ActionSetCode), 1f, false);
        gameEntity.CreateSkeletonWithActionSet(ref animationSystemData);
        gameEntity.SetFrame(ref itemFrame);
        gameEntity.Skeleton.SetAgentActionChannel(0, this.act_tableau_hand_armor_pose);
        gameEntity.AddMultiMeshToSkeleton(meshForInventory);
        gameEntity.Skeleton.TickAnimationsAndForceUpdate(0.01f, itemFrame, true);
      }
      else if ((NativeObject) meshForInventory != (NativeObject) null)
      {
        if (item.WeaponComponent != null)
        {
          switch (item.WeaponComponent.PrimaryWeapon.WeaponClass)
          {
            case WeaponClass.Bolt:
            case WeaponClass.ThrowingAxe:
            case WeaponClass.ThrowingKnife:
            case WeaponClass.Javelin:
              gameEntity = GameEntity.CreateEmpty(scene);
              MetaMesh copy1 = meshForInventory.CreateCopy();
              copy1.Frame = itemFrame;
              gameEntity.AddMultiMesh(copy1);
              MetaMesh copy2 = meshForInventory.CreateCopy();
              copy2.Frame = itemFrame1;
              gameEntity.AddMultiMesh(copy2);
              MetaMesh copy3 = meshForInventory.CreateCopy();
              copy3.Frame = itemFrame2;
              gameEntity.AddMultiMesh(copy3);
              break;
            default:
              gameEntity = scene.AddItemEntity(ref itemFrame, meshForInventory);
              break;
          }
        }
        else
        {
          gameEntity = scene.AddItemEntity(ref itemFrame, meshForInventory);
          if (item.Type == ItemObject.ItemTypeEnum.HorseHarness && item.ArmorComponent != null)
          {
            MetaMesh copy4 = MetaMesh.GetCopy(item.ArmorComponent.ReinsMesh, mayReturnNull: true);
            if ((NativeObject) copy4 != (NativeObject) null)
              gameEntity.AddMultiMesh(copy4);
          }
        }
      }
      else
        MBDebug.ShowWarning("[DEBUG]Item with " + rosterElement.EquipmentElement.Item.StringId + "[DEBUG] string id cannot be found");
      gameEntity.SetVisibilityExcludeParents(false);
      return gameEntity;
    }

    private void GetPoseParamsFromCharacterCode(
      CharacterCode characterCode,
      out string poseName,
      out bool hasHorse)
    {
      hasHorse = false;
      if (characterCode.IsHero)
      {
        int num = MBRandom.NondeterministicRandomInt % 8;
        poseName = "lord_" + (object) num;
      }
      else
      {
        poseName = "troop_villager";
        int index1 = -1;
        int index2 = -1;
        Equipment equipment = characterCode.CalculateEquipment();
        switch (characterCode.FormationClass)
        {
          case FormationClass.Infantry:
          case FormationClass.Cavalry:
          case FormationClass.NumberOfDefaultFormations:
          case FormationClass.HeavyInfantry:
          case FormationClass.LightCavalry:
          case FormationClass.HeavyCavalry:
          case FormationClass.NumberOfRegularFormations:
          case FormationClass.Bodyguard:
            for (int index3 = 0; index3 < 4; ++index3)
            {
              if (equipment[index3].Item?.PrimaryWeapon != null)
              {
                if (index2 == -1 && equipment[index3].Item.ItemFlags.HasAnyFlag<ItemFlags>(ItemFlags.HeldInOffHand))
                  index2 = index3;
                if (index1 == -1 && equipment[index3].Item.PrimaryWeapon.WeaponFlags.HasAnyFlag<WeaponFlags>(WeaponFlags.MeleeWeapon))
                  index1 = index3;
              }
            }
            break;
          case FormationClass.Ranged:
          case FormationClass.HorseArcher:
            for (int index4 = 0; index4 < 4; ++index4)
            {
              if (equipment[index4].Item?.PrimaryWeapon != null)
              {
                if (index2 == -1 && equipment[index4].Item.ItemFlags.HasAnyFlag<ItemFlags>(ItemFlags.HeldInOffHand))
                  index2 = index4;
                if (index1 == -1 && equipment[index4].Item.PrimaryWeapon.WeaponFlags.HasAnyFlag<WeaponFlags>(WeaponFlags.RangedWeapon))
                  index1 = index4;
              }
            }
            break;
        }
        if (index1 != -1)
        {
          switch (equipment[index1].Item.PrimaryWeapon.WeaponClass)
          {
            case WeaponClass.OneHandedSword:
            case WeaponClass.OneHandedAxe:
              if (index2 == -1)
              {
                poseName = "troop_infantry_sword1h";
                break;
              }
              if (equipment[index2].Item.PrimaryWeapon.IsShield)
              {
                poseName = "troop_infantry_sword1h";
                break;
              }
              break;
            case WeaponClass.TwoHandedSword:
            case WeaponClass.TwoHandedAxe:
            case WeaponClass.TwoHandedMace:
              poseName = "troop_infantry_sword2h";
              break;
            case WeaponClass.OneHandedPolearm:
            case WeaponClass.TwoHandedPolearm:
              poseName = "troop_spear";
              break;
            case WeaponClass.LowGripPolearm:
            case WeaponClass.Javelin:
              poseName = "troop_spear";
              break;
            case WeaponClass.Bow:
              poseName = "troop_bow";
              break;
            case WeaponClass.Crossbow:
              poseName = "troop_crossbow";
              break;
          }
        }
        if (equipment[EquipmentIndex.ArmorItemEndSlot].IsEmpty)
          return;
        if (index1 != -1)
        {
          HorseComponent horseComponent = equipment[EquipmentIndex.ArmorItemEndSlot].Item.HorseComponent;
          int num1;
          if (horseComponent == null)
          {
            num1 = 0;
          }
          else
          {
            int? familyType = horseComponent.Monster?.FamilyType;
            int num2 = 2;
            num1 = familyType.GetValueOrDefault() == num2 & familyType.HasValue ? 1 : 0;
          }
          bool flag = num1 != 0;
          EquipmentElement equipmentElement = equipment[index1];
          switch (equipmentElement.Item.Type)
          {
            case ItemObject.ItemTypeEnum.OneHandedWeapon:
              if (index2 == -1)
              {
                poseName = "troop_cavalry_sword";
                break;
              }
              equipmentElement = equipment[index2];
              if (equipmentElement.Item.PrimaryWeapon.IsShield)
              {
                poseName = "troop_cavalry_sword";
                break;
              }
              break;
            case ItemObject.ItemTypeEnum.Bow:
              poseName = "troop_cavalry_archer";
              break;
            default:
              poseName = "troop_cavalry_lance";
              break;
          }
          if (flag)
            poseName = "camel_" + poseName;
        }
        hasHorse = true;
      }
    }

    private GameEntity CreateCraftingPieceBaseEntity(
      CraftingPiece craftingPiece,
      string ItemType,
      Scene scene,
      ref Camera camera)
    {
      MatrixFrame placementFrame = MatrixFrame.Identity;
      bool flag1 = false;
      string tag1 = "craftingPiece_cam";
      string tag2 = "craftingPiece_frame";
      if (craftingPiece.PieceType == CraftingPiece.PieceTypes.Blade)
      {
        switch (ItemType)
        {
          case "OneHandedAxe":
          case "ThrowingAxe":
            tag1 = "craft_axe_camera";
            tag2 = "craft_axe";
            break;
          case "TwoHandedAxe":
            tag1 = "craft_big_axe_camera";
            tag2 = "craft_big_axe";
            break;
          case "Dagger":
          case "ThrowingKnife":
          case "TwoHandedPolearm":
          case "Pike":
          case "Javelin":
            tag1 = "craft_spear_blade_camera";
            tag2 = "craft_spear_blade";
            break;
          case "Mace":
          case "TwoHandedMace":
            tag1 = "craft_mace_camera";
            tag2 = "craft_mace";
            break;
          default:
            tag1 = "craft_blade_camera";
            tag2 = "craft_blade";
            break;
        }
        flag1 = true;
      }
      else if (craftingPiece.PieceType == CraftingPiece.PieceTypes.Pommel)
      {
        tag1 = "craft_pommel_camera";
        tag2 = "craft_pommel";
        flag1 = true;
      }
      else if (craftingPiece.PieceType == CraftingPiece.PieceTypes.Guard)
      {
        tag1 = "craft_guard_camera";
        tag2 = "craft_guard";
        flag1 = true;
      }
      else if (craftingPiece.PieceType == CraftingPiece.PieceTypes.Handle)
      {
        tag1 = "craft_handle_camera";
        tag2 = "craft_handle";
        flag1 = true;
      }
      bool flag2 = false;
      if (flag1)
      {
        GameEntity entityWithTag1 = scene.FindEntityWithTag(tag1);
        if ((NativeObject) entityWithTag1 != (NativeObject) null)
        {
          camera = Camera.CreateCamera();
          Vec3 dofParams = new Vec3();
          entityWithTag1.GetCameraParamsFromCameraScript(camera, ref dofParams);
        }
        GameEntity entityWithTag2 = scene.FindEntityWithTag(tag2);
        if ((NativeObject) entityWithTag2 != (NativeObject) null)
        {
          placementFrame = entityWithTag2.GetGlobalFrame();
          entityWithTag2.SetVisibilityExcludeParents(false);
          flag2 = true;
        }
      }
      else
      {
        GameEntity entityWithTag = scene.FindEntityWithTag("old_system_item_frame");
        if ((NativeObject) entityWithTag != (NativeObject) null)
        {
          placementFrame = entityWithTag.GetGlobalFrame();
          entityWithTag.SetVisibilityExcludeParents(false);
        }
      }
      if ((NativeObject) camera == (NativeObject) null)
      {
        camera = Camera.CreateCamera();
        camera.SetViewVolume(false, -1f, 1f, -0.5f, 0.5f, 0.01f, 100f);
        MatrixFrame identity = MatrixFrame.Identity;
        identity.origin -= identity.rotation.u * 7f;
        identity.rotation.u *= -1f;
        camera.Frame = identity;
      }
      if (!flag2)
        placementFrame = craftingPiece.GetCraftingPieceFrameForInventory();
      MetaMesh copy = MetaMesh.GetCopy(craftingPiece.MeshName);
      GameEntity craftingPieceBaseEntity = (GameEntity) null;
      if ((NativeObject) copy != (NativeObject) null)
        craftingPieceBaseEntity = scene.AddItemEntity(ref placementFrame, copy);
      else
        MBDebug.ShowWarning("[DEBUG]craftingPiece with " + craftingPiece.StringId + "[DEBUG] string id cannot be found");
      craftingPieceBaseEntity.SetVisibilityExcludeParents(false);
      return craftingPieceBaseEntity;
    }

    private GameEntity CreateItemBaseEntity(ItemObject item, Scene scene, ref Camera camera)
    {
      MatrixFrame identity1 = MatrixFrame.Identity;
      MatrixFrame identity2 = MatrixFrame.Identity;
      MatrixFrame identity3 = MatrixFrame.Identity;
      this.GetItemPoseAndCamera(item, scene, ref camera, ref identity1, ref identity2, ref identity3);
      return this.AddItem(scene, item, identity1, identity2, identity3);
    }

    private GameEntity CreateCharacterBaseEntity(
      CharacterCode characterCode,
      Scene scene,
      ref Camera camera,
      bool isBig)
    {
      string poseName;
      this.GetPoseParamsFromCharacterCode(characterCode, out poseName, out bool _);
      string tag1 = poseName + "_pose";
      string tag2 = isBig ? poseName + "_cam" : poseName + "_cam_small";
      GameEntity entityWithTag1 = scene.FindEntityWithTag(tag1);
      if ((NativeObject) entityWithTag1 == (NativeObject) null)
        return (GameEntity) null;
      entityWithTag1.SetVisibilityExcludeParents(true);
      GameEntity entity = GameEntity.CopyFromPrefab(entityWithTag1);
      entity.Name = entityWithTag1.Name + "Instance";
      entity.RemoveTag(tag1);
      scene.AttachEntity(entity);
      entity.SetVisibilityExcludeParents(true);
      entityWithTag1.SetVisibilityExcludeParents(false);
      GameEntity entityWithTag2 = scene.FindEntityWithTag(tag2);
      Vec3 dofParams = new Vec3();
      camera = Camera.CreateCamera();
      if ((NativeObject) entityWithTag2 != (NativeObject) null)
      {
        entityWithTag2.GetCameraParamsFromCameraScript(camera, ref dofParams);
        camera.Frame = entityWithTag2.GetGlobalFrame();
      }
      return entity;
    }

    private GameEntity FillEntityWithPose(
      CharacterCode characterCode,
      GameEntity poseEntity,
      Scene scene)
    {
      if (characterCode.IsEmpty)
      {
        Debug.FailedAssert("Trying to fill entity with empty character code", "C:\\Develop\\MB3\\Source\\Bannerlord\\TaleWorlds.MountAndBlade.View\\Tableaus\\TableauCacheManager.cs", nameof (FillEntityWithPose), 1536);
        return poseEntity;
      }
      if (string.IsNullOrEmpty(characterCode.EquipmentCode))
      {
        Debug.FailedAssert("Trying to fill entity with invalid equipment code", "C:\\Develop\\MB3\\Source\\Bannerlord\\TaleWorlds.MountAndBlade.View\\Tableaus\\TableauCacheManager.cs", nameof (FillEntityWithPose), 1542);
        return poseEntity;
      }
      if (TaleWorlds.Core.FaceGen.GetBaseMonsterFromRace(characterCode.Race) == null)
      {
        Debug.FailedAssert("There are no monster data for the race: " + (object) characterCode.Race, "C:\\Develop\\MB3\\Source\\Bannerlord\\TaleWorlds.MountAndBlade.View\\Tableaus\\TableauCacheManager.cs", nameof (FillEntityWithPose), 1549);
        return poseEntity;
      }
      if (TableauCacheManager.Current != null && (NativeObject) poseEntity != (NativeObject) null)
      {
        this.GetPoseParamsFromCharacterCode(characterCode, out string _, out bool _);
        CharacterSpawner characterSpawner = poseEntity.GetScriptComponents<CharacterSpawner>().First<CharacterSpawner>();
        characterSpawner.SetCreateFaceImmediately(false);
        characterSpawner.InitWithCharacter(characterCode);
      }
      return poseEntity;
    }

    public static Camera CreateDefaultBannerCamera()
    {
      return TableauCacheManager.CreateCamera(0.333333343f, 0.6666667f, -0.6666667f, -0.333333343f, 1f / 1000f, 510f);
    }

    public static Camera CreateNineGridBannerCamera()
    {
      return TableauCacheManager.CreateCamera(0.0f, 1f, -1f, 0.0f, 1f / 1000f, 510f);
    }

    private static Camera CreateCamera(
      float left,
      float right,
      float bottom,
      float top,
      float near,
      float far)
    {
      Camera camera = Camera.CreateCamera();
      MatrixFrame identity = MatrixFrame.Identity;
      identity.origin.z = 400f;
      camera.Frame = identity;
      camera.LookAt(new Vec3(z: 400f), new Vec3(), new Vec3(y: 1f));
      camera.SetViewVolume(false, left, right, bottom, top, near, far);
      return camera;
    }

    private struct RenderDetails
    {
      public List<Action<Texture>> Actions { get; private set; }

      public RenderDetails(List<Action<Texture>> setActionList) => this.Actions = setActionList;
    }

    private struct CustomPoseParameters
    {
      public string CameraTag;
      public string FrameTag;
      public float DistanceModifier;
      public TableauCacheManager.CustomPoseParameters.Alignment FocusAlignment;

      public enum Alignment
      {
        Center,
        Top,
        Bottom,
      }
    }
  }
}
